package com.allianz.webapps.secondController;

import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.File;




import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.URL;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSON;

import org.apache.commons.io.FileUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.Assert;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import sun.misc.BASE64Decoder;
import cn.org.bjca.anysign.client.net.utils.FileUtil;
import cn.org.bjca.anysign.client.security.SecurityEngineDeal;
import cn.org.bjca.anysign.model.AnywriteSignInfo;
import cn.org.bjca.pdf.model.DocumentType;

import com.allianz.frame.utils.ApplicationContextUtil;
import com.allianz.frame.utils.Pdf2TifUtil;
import com.allianz.frame.utils.PropertiesUtil;
import com.allianz.frame.utils.StringUtil;
import com.allianz.webapps.common.CustomerContextHolder;
import com.allianz.webapps.dao.EReceiptMapper;
import com.allianz.webapps.dbpojo.EReceipt;
import com.allianz.webapps.dbpojo.Note;
import com.allianz.webapps.https.interfaces.bjca.BJCApojo;
import com.allianz.webapps.https.interfaces.bjca.PdfMessage;
import com.allianz.webapps.https.interfaces.util.HttpsUtil;
import com.allianz.webapps.service.EReceiptService;
import com.allianz.webapps.service.impl.CaPdfService;
import com.allianz.webapps.service.impl.ImageUploadService;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;


@Controller
@RequestMapping(value="/note")
public class EReceiptController {
	
	private static String BASEPATH = PropertiesUtil.getResourcePath();//app/azclportal_resource/resources/temp/
	
	protected final Logger log = LoggerFactory.getLogger(getClass());
	
	@Autowired
	private ObjectMapper objectMapper;
	
	@Autowired
	private EReceiptService eReceiptService;
	
	@Autowired
	private EReceiptMapper eReceiptMapper;
	
	/**
	 * 跳转至电子回执主页
	 * 
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "eReceipt")
	public String eReceipt(HttpServletRequest request,
			HttpServletResponse response) {
		return "views/page/noteDeal/contractReceipt";
	}
	
	@RequestMapping("/ifEReceipt")
	@ResponseBody
	public Map<String, Object> ifEReceipt(@RequestParam(value = "jsonParam") String jsonParam,HttpServletRequest request, HttpServletResponse response)throws Exception {
		CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_ALLIANZ);
		EReceipt qc = objectMapper.readValue(jsonParam, EReceipt.class);
		return eReceiptService.ifEReceipt(qc.getContractId());
		
	}
	
	@RequestMapping("/getInsured")
	@ResponseBody
	public Map<String, Object> getProductName(@RequestParam(value = "jsonParam") String jsonParam,HttpServletRequest request, HttpServletResponse response)throws Exception {
		CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_ALLIANZ);
		EReceipt qc = objectMapper.readValue(jsonParam, EReceipt.class);
		return eReceiptService.queryProduct(qc.getContractId());
	}
	
	@RequestMapping(value = "/downloadEReceipt")
	@ResponseBody
	public Map<String,Object> downloadEReceipt(@RequestParam(value = "jsonParam") String jsonParam,HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_ALLIANZ);
		Map<String,Object> map = new HashMap<String,Object>();
		EReceipt qc = objectMapper.readValue(jsonParam, EReceipt.class);
		String contractId = qc.getContractId();
		String policyRef = qc.getPolicyRef();
		String pdfType = qc.getPdfType();
		
		if(eReceiptService.ifSign(contractId)){
			//签名路径
			String tempPath = PropertiesUtil.getResourcePath() + "private/eReceipt/pdf/"+policyRef + "/" + contractId +"/unsign/";
//			tempPath = "E://eReceipt/pdf/"+policyRef + "/" + contractId +"/unsign/";
			File tempPathFile = new File(tempPath);
			tempPathFile.mkdirs();
			String pdfTempPath = tempPath + pdfType + ".pdf";
			String pdfUrl = PropertiesUtil.getProperty("quoPdfURLPrefix")+"NL5021?contractId="+contractId+"&partner=NEWTOUCH&sign="+StringUtil.getAZCLmd5(contractId+"NEWTOUCH");
//			pdfUrl = "http://portal.allianz.com.cn/PortalDev/Interface/iPad/NL5021?contractId=4691742&partner=NEWTOUCH&sign=5E21E364492DA8AD05C2A3907F4B47BC";
			log.debug(pdfUrl);
			HttpsUtil.httpsPost_pdf_download(pdfUrl, pdfTempPath);
			File originalPdf = new File(pdfTempPath);

			List<File> jpgs = Pdf2TifUtil.pdf2jpg(originalPdf, tempPath);
			map.put("recptStatus", "unSign");
			map.put("len", jpgs.size()+"");
		}else{
			map.put("recptStatus", "signed");
		}
		
		
		
		return map;
	}
	
	@RequestMapping(value = "/showJpgs")
	public void showJpgs(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		String id = request.getParameter("id");
		String contractId = request.getParameter("contractId");
		String policyRef = request.getParameter("policyRef");
		String pdfType = request.getParameter("pdfType");
		//签名路径
		String tempPath = PropertiesUtil.getResourcePath() + "private/eReceipt/pdf/"+policyRef + "/" + contractId +"/unsign/";
//		tempPath = "E://eReceipt/pdf/"+policyRef + "/" + contractId +"/unsign/";
		
		String jpgPath = tempPath +pdfType+".pdf"+ id + ".jpg";
		File f = new File(jpgPath);
		
		String type = "jpg";
		int length = 0;
		ServletOutputStream op;
		try {
			op = response.getOutputStream();
		} catch (IOException e) {
			throw new IOException("io流错误");
		}
		response.setContentLength((int) f.length());
		response.setContentType("image/jpeg");
		response.setHeader("Content-Disposition", "inline; filename=" + type);
		response.setHeader("Pragma", "No-cache");
		response.setHeader("Cache-Control", "No-cache");
		response.setHeader("Cache-Control", "no-store");
		response.setDateHeader("Expires", 0);

		byte[] bytes = new byte[1024];
		DataInputStream in;
		try {
			in = new DataInputStream(new FileInputStream(f));
			while ((in != null) && ((length = in.read(bytes)) != -1)) {
				op.write(bytes, 0, length);
			}
			op.close();
			in.close();
			response.flushBuffer();
		} catch (FileNotFoundException e) {
			throw new Exception("文件未找到");
		} catch (IOException e) {
			throw new IOException("io流错误");
		}
	}
	/**
	 * 展示电子回执的pdf（转jpg）信息
	 * 
	 * @param jsonParam
	 * @param request
	 * @param response
	 * @throws Exception
	 */
	@RequestMapping(value = "/showEReceipt")
	public void showEReceipt(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		String contractId = request.getParameter("contractId");
		String policyRef = request.getParameter("policyRef");
		String pdfType = request.getParameter("pdfType");
		
		
		//签名路径
		String tempPath = PropertiesUtil.getResourcePath() + "private/eReceipt/pdf/"+policyRef + "/" + contractId +"/unsign/";
//		tempPath = "E://eReceipt/pdf/"+policyRef + "/" + contractId +"/unsign/";
		File tempPathFile = new File(tempPath);
		tempPathFile.mkdirs();
		String pdfTempPath = tempPath + pdfType + ".pdf";
		String pdfUrl = PropertiesUtil.getProperty("quoPdfURLPrefix")+"NL5021?contractId="+contractId+"&partner=NEWTOUCH&sign="+StringUtil.getAZCLmd5(contractId+"NEWTOUCH");
//		pdfUrl = "http://portal.allianz.com.cn/PortalDev/Interface/iPad/NL5021?contractId=4691742&partner=NEWTOUCH&sign=5E21E364492DA8AD05C2A3907F4B47BC";
		log.debug(pdfUrl);
		HttpsUtil.httpsPost_pdf_download(pdfUrl, pdfTempPath);
		File originalPdf = new File(pdfTempPath);

		List<File> jpgs = Pdf2TifUtil.pdf2jpg(originalPdf, tempPath);

		File f = jpgs.get(0);
			String type = "jpg";
			int length = 0;
//			length = jpgs.size();
			ServletOutputStream op;
			try {
				op = response.getOutputStream();
			} catch (IOException e) {
				throw new IOException("io流错误");
			}
			response.setContentLength((int) f.length());
			response.setContentType("image/jpeg");
			response.setHeader("Content-Disposition", "inline; filename=" + type);
			response.setHeader("Pragma", "No-cache");
			response.setHeader("Cache-Control", "No-cache");
			response.setHeader("Cache-Control", "no-store");
			response.setDateHeader("Expires", 0);

			byte[] bytes = new byte[1024];
			DataInputStream in;
			try {
				in = new DataInputStream(new FileInputStream(f));
				while ((in != null) && ((length = in.read(bytes)) != -1)) {
					op.write(bytes, 0, length);
				}
				op.close();
				in.close();
				response.flushBuffer();
			} catch (FileNotFoundException e) {
				throw new Exception("文件未找到");
			} catch (IOException e) {
				throw new IOException("io流错误");
			}

		
	}
	
	@RequestMapping(value="eReceipt_uploadCA")
	@ResponseBody
	public void eReceipt_uploadCA(@RequestParam(value="jsonParam")String jsonParam,HttpServletRequest request,HttpServletResponse response) throws Exception{
		
		
		
		/*
		 * 准备数据  pdfMessage 图片和pdf
		 * 		 ca中有type  policyRef
		 */
		BJCApojo ca;
		try {
			 ca =objectMapper.readValue(jsonParam,BJCApojo.class);
		} catch (Exception e) {
			throw new Exception("签字数据异常,请确认已完成签字拍照");
		}
		List<PdfMessage> pdfMessage = ca.getPdfMessageList();
		if(pdfMessage.size()==0){
			throw new Exception("签字数据异常,请确认已完成签字拍照");
		}
		String policyRef = ca.getPolicyRef();
		String contractId= ca.getSign();
		String insured = ca.getInsured();
		String unsignPdfPath;
		String signedPdfPath;
		
		String flagFileString_photo_Directory = BASEPATH+"private/eReceipt_"+policyRef+"_"+contractId+"/";
		String note = "eReceipt";
		List<String> typeL= new ArrayList<String>();
		typeL.add(ImageUploadService.returnType("C"));
		typeL.add(ImageUploadService.returnType("M"));
		typeL.add(ImageUploadService.returnType("O"));
		typeL.add(ImageUploadService.returnType("D"));
		typeL.add(ImageUploadService.returnType("S"));
		typeL.add(ImageUploadService.returnType("H"));
		typeL.add(ImageUploadService.returnType("L"));
//		ImageUploadService.imageUploadMethod(policyRef, note, typeL, flagFileString_photo_Directory,ImageUploadService.getIP(request),contractId);
		/*
		 * 准备数据   循环数据 上传至影像系统
		 * 		 
		 */
		
		for(PdfMessage pdf:pdfMessage){
			/*
			 * 上传照片
			 * 		 
			 */
			String encode = pdf.getEncode();
			String encodePath = BASEPATH+"private/eReceipt/pdf/"+policyRef+"/"+contractId+"/"+"unsign/" + pdf.getPdfType()+".txt";
			FileWriter fw = null;
			if(StringUtil.isNull(encode)){
				throw new Exception("加密包不能为空");
			}else{
				fw = new FileWriter(encodePath);
				fw.write(encode);
				fw.flush();
				fw.close();
			}
			List<String> photoList = pdf.getPhotoList();
			for(int i=0;i<photoList.size();i++){
				ImageUploadService.uploadUtil(photoList.get(i), BASEPATH+"private/eReceipt/pdf/"+policyRef+"/"+contractId+"/"+"signed/"+"1175_"+i+".jpg");
			}
			
			
			/*
			 * 将http下的pdf下载到未签名的文件夹中
			 * 		 
			 */
			//未签名的pdf目录路径：
			unsignPdfPath = BASEPATH+"private/eReceipt/pdf/"+policyRef+"/"+contractId+"/"+"unsign/"+pdf.getPdfType()+".pdf";
			//签名后的pdf目录路径：
			signedPdfPath = BASEPATH+"private/eReceipt/pdf/"+policyRef+"/"+contractId+"/"+"signed/"+pdf.getPdfType()+".pdf";
			
			//先生成文件 再复制
			/*String pdfUrl = pdf.getPdfURL();
			File file = new File(unsignPdfPath);
			if(!file.exists()){
				file.getParentFile().mkdirs();
				file.createNewFile();
			};
			HttpsUtil.httpsPost_pdf_download(pdfUrl,unsignPdfPath);*/
			/*
			 * 调用ca接口  生成合成pdf
			 * 		 
			 */
			
			int repeat = 5;
			boolean result = false;
			while(repeat>0){
				result = CaPdfService.makeCaPdf(encodePath, unsignPdfPath, signedPdfPath, ca.getPolicyRef());
				if(result)
					break;
				repeat--;
				Thread.sleep(2000);
			}
			if(!result){
				throw new Exception("CA异常,请待会重试");
			}
			
			/*
			 * 生成tif文件 
			 * 
			 */
			File signedPdfPathFile = new File(signedPdfPath);
			boolean tifResult = CaPdfService.pdfToTif(signedPdfPathFile, signedPdfPathFile.getParentFile().getAbsolutePath()+File.separator, pdf.getPdfType());
			if(!tifResult){
				throw new Exception("tif合成工具异常,请待会重试");
			}
			
			/*
			 * 上传影像
			 * 
			 */
			//影像系统下的文件夹
			Map<String,List<File>>  filesMap = new HashMap<String,List<File>>();
			List<String> typeList= new ArrayList<String>();
			typeList.add("1175");
			typeList.add(pdf.getPdfType());
			filesMap=ImageUploadService.getPhotoMap(policyRef, policyRef, typeList, signedPdfPathFile.getParentFile().getAbsolutePath()+File.separator);
			Date date = new Date();
//			boolean shadowXMLandFolderCreateResult =ImageUploadService.shadowXMLandFolderCreate(policyRef, note, ImageUploadService.getIP(request), filesMap, date,contractId);
			boolean shadowXMLandFolderCreateResult = shadowXMLandFolderCreate(policyRef, note, ImageUploadService.getIP(request), filesMap, date,contractId,insured);
			if(!shadowXMLandFolderCreateResult){
				throw new Exception("影像上传失败");
			}
		}
		
	}
	
	
	@RequestMapping(value="eReceiptUpdateState")
	@ResponseBody
	public Map<String,Object> updateState(@RequestParam(value="jsonParam")String jsonParam,HttpServletRequest request,HttpServletResponse response) throws Exception{
		CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_ALLIANZ);
		Map<String,Object> map = new HashMap<String,Object>();
		EReceipt eReceipt =objectMapper.readValue(jsonParam,EReceipt.class);
//		int result = eReceiptService.modifyEReceipt(eReceipt.getContractId());
		int result = eReceiptService.updateEReceipt(eReceipt.getContractId());
		map.put("result", result);
		return map;
	}
	
	
	//生成影像上传的xml文件和目录
	private static boolean shadowXMLandFolderCreate(String policyRef,String note,String ipHost,Map<String,List<File>> filesMap,Date date,String contractId,String insured) throws IOException{
			DateFormat df = new SimpleDateFormat("yyyyMMddhhmmss");
			
			String folderPath = PropertiesUtil.getResourcePath()+"private/shadow_upload/"+note+"_"+policyRef+"_"+contractId+"/";
			File folderPathFile = new File(folderPath);
			if(folderPathFile.exists()){
				if(folderPathFile.isFile()){
					folderPathFile.delete();
				}
			}else{
				folderPathFile.mkdirs();
			}

			FileWriter fw;
			try {
				fw = new FileWriter(folderPath+"1.xml");
			} catch (IOException e) {
				throw new IOException("xml文件生成失败");
			}
			Document document = DocumentHelper.createDocument();
			// 创建ImageBatch结点
			Element imageBatch = document.addElement("ImageBatch");
			// 生成ImageBatch的子接点policys
			Element policys = imageBatch.addElement("policys");
			// 生成policys的子接点policy(这里就是文件的循环了）

			Set<Entry<String,List<File>>> set = filesMap.entrySet();
			for(Entry<String,List<File>> en : set){
				String list_fileType = en.getKey();
				List<File> fileList = en.getValue();
				Element policy = policys.addElement("policy");
				Element policyNo = policy.addElement("policyNo");
					policyNo.addText(policyRef);//保单号
				Element uploadUser = policy.addElement("uploadUser");
					uploadUser.addText("APP");
				Element fileType = policy.addElement("fileType");
					fileType.addText(en.getKey());
				Element taskType = policy.addElement("taskType");
					taskType.addText("03");
				Element scanTime = policy.addElement("scanTime");
					scanTime.addText(df.format(date));
				Element taskId = policy.addElement("taskId");
					taskId.addText(insured);
//				Element taskId = policy.addElement("type");
//					taskId.addText(note);
				Element source = policy.addElement("source");
					source.addText("2");
				Element fileNum = policy.addElement("fileNum");
					fileNum.addText(fileList.size()+"");
				Element ip = policy.addElement("ip");
					ip.addText(ipHost);
				Element files = policy.addElement("files");
				ImageUploadService.sortList(fileList);
				for(File f:fileList){
					Element filename = files.addElement("filename");
					String fileTempName = f.getName();
					if("photo".equals(list_fileType)){
						fileTempName = fileTempName.substring(0, fileTempName.length());
					}
					filename.addText(fileTempName);
				}
			}
			// 设置文件编码
			OutputFormat xmlFormat = new OutputFormat();
			xmlFormat.setEncoding("UTF-8");
			// 设置换行
			xmlFormat.setNewlines(true);
			// 生成缩进
			xmlFormat.setIndent(true);
			// 使用1个制表符进行缩进, 可以兼容文本编辑器
			xmlFormat.setIndent("\t");
			
			// 创建写文件方法
			XMLWriter xmlWriter = new XMLWriter(fw, xmlFormat);
			// 写入文件
			try {
				xmlWriter.write(document);
				// 关闭
				xmlWriter.close();
			} catch (IOException e) {
				throw new IOException("xml文件写入失败");
			}
			
			boolean bo = true;
			for(Entry<String,List<File>> en : set){
				String file_type = en.getKey();
				List<File> files = en.getValue();
				for(File f:files){
					if(f.length()>0){
						String file_name = f.getName();
						if("photo".equals(file_type)){
							file_name = file_name.substring(0,file_name.length());
						}
						File endAbsolutePath = new File(folderPath+file_name);
						int byteCount;
						try {
							byteCount = FileCopyUtils.copy(f, endAbsolutePath);
							if(byteCount!=f.length()){
								bo=false;
							}
						} catch (IOException e) {
							throw new IOException("照片上传失败");
						}
					}
				}
			}
			if(bo){
				return true;
			}
			return false;
		}
}
